package com.sdry.utils;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelFileUtils {
	/**
	 * 文件保存项目相对路径
	 */
	public final static String FILE_PATH = "uploadFile\\";
	/**
	 * 导出模板
	 * 
	 * @return
	 * @throws IOException 
	 */
	public static void exportExcelFile(String title,
			HttpServletResponse response,HttpServletRequest request) throws IOException {
		// 读取内容
		String filePath= request.getSession().getServletContext()
				.getRealPath("/")+FILE_PATH+title+".xls";
		// 创建 Excel 文件的输入流对象
		FileInputStream excelFileInputStream = new FileInputStream(filePath);
		// XSSFWorkbook 就代表一个 Excel 文件
		// 创建其对象，就打开这个 Excel 文件
		HSSFWorkbook workbook = new HSSFWorkbook(excelFileInputStream);
		// 输入流使用后，及时关闭！这是文件流操作中极好的一个习惯！
		excelFileInputStream.close();
		daochu(title,workbook,response);
	}
	public static void exportExcel(String title,HttpServletRequest request,
			HttpServletResponse response, List<List<String>> lists) throws IOException{
		// 读取内容
		String filePath= request.getSession().getServletContext()
				.getRealPath("/")+FILE_PATH+title+".xls";
		// 创建 Excel 文件的输入流对象
		FileInputStream excelFileInputStream = new FileInputStream(filePath);
		// XSSFWorkbook 就代表一个 Excel 文件
		// 创建其对象，就打开这个 Excel 文件
		HSSFWorkbook workbook = new HSSFWorkbook(excelFileInputStream);
		// 输入流使用后，及时关闭！这是文件流操作中极好的一个习惯！
		excelFileInputStream.close();
		// 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
		HSSFSheet sheet = workbook.createSheet(title);
		
		// 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
		HSSFRow row = sheet.createRow((int) 0);
		for (int i = 0; i < lists.size(); i++) {
			row = sheet.getRow(i);
			List<String> listob = lists.get(i);
			for (int j = 0; j < listob.size(); j++) {
				row.getCell(j).setCellValue((listob.get(j)));
			}

		}
		lists = null;
		daochu(title,workbook,response);
	}
	/**
	 * 导出文件
	 * @param title 文件名
	 * @param wb HSSFWorkbook
	 * @param response 
	 * @throws UnsupportedEncodingException
	 */
	public static void daochu(String title,HSSFWorkbook wb,HttpServletResponse response) throws UnsupportedEncodingException{
		// 第六步，将文件存到指定位置
		Date now = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");// 可以方便地修改日期格式
		String nowtime = dateFormat.format(now);

		String fileName = title + nowtime + ".xls";
		fileName = new String(fileName.getBytes("GBK"), "iso8859-1");
		try {
			response.reset();
			response.setHeader("Content-Disposition", "attachment;filename="
					+ fileName);// 指定下载的文件名
			response.setContentType("application/vnd.ms-excel");
			response.setHeader("Pragma", "no-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			OutputStream output = response.getOutputStream();
			BufferedOutputStream bufferedOutPut = new BufferedOutputStream(
					output);
			bufferedOutPut.flush();
			wb.write(bufferedOutPut);
			bufferedOutPut.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 读取内容
	public static List<List<String>> readXls(String filePath,
			HttpServletRequest request, int num) throws IOException {
		List<List<String>> lists = new ArrayList();
		// 创建 Excel 文件的输入流对象
		FileInputStream excelFileInputStream = new FileInputStream(filePath);
		// XSSFWorkbook 就代表一个 Excel 文件
		// 创建其对象，就打开这个 Excel 文件
		HSSFWorkbook workbook = new HSSFWorkbook(excelFileInputStream);
		// 输入流使用后，及时关闭！这是文件流操作中极好的一个习惯！
		excelFileInputStream.close();
		// XSSFSheet 代表 Excel 文件中的一张表格
		// 我们通过 getSheetAt(0) 指定表格索引来获取对应表格
		// 注意表格索引从 0 开始！
		HSSFSheet sheet = workbook.getSheetAt(0);
		// 步骤三 ： 循环读取表格并输出其内容
		// 开始循环表格数据,表格的行索引从 0 开始
		// employees.xlsx 第一行是标题行，我们从第二行开始, 对应的行索引是 1
		// sheet.getLastRowNum() : 获取当前表格中最后一行数据对应的行索引
		// 获得总列数 int coloumNum=sheet.getRow(0).getPhysicalNumberOfCells();
		// 获得总行数 int rowNum=sheet.getLastRowNum();
		for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
			// XSSFRow 代表一行数据
			HSSFRow row = sheet.getRow(rowIndex);
			if (row == null) {
				continue;
			}
			List<String> list = new ArrayList<String>();
			for (int i = 0; i < num; i++) {
				String cellStr = null;
				if (null != row.getCell(i)) {
					int dataFormat = row.getCell(i).getCellStyle()
							.getDataFormat();
					if (dataFormat == 14 || dataFormat == 176
							|| dataFormat == 178 || dataFormat == 180
							|| dataFormat == 181 || dataFormat == 182) {
						/*
						 * cellStr =
						 * ReadExcleUtils.getDateValue2007(row.getCell(i));
						 */
						Date theDate = row.getCell(i).getDateCellValue();
						SimpleDateFormat dff = new SimpleDateFormat(
								"yyyy-MM-dd");
						cellStr = dff.format(theDate);
					} else {
						switch (row.getCell(i).getCellType()) {
						case HSSFCell.CELL_TYPE_NUMERIC:// 数值
							BigDecimal db = new BigDecimal(row.getCell(i)
									.getNumericCellValue());
							if (db.toString().indexOf(".") != -1) {
								java.text.DecimalFormat dfomat = new java.text.DecimalFormat(
										"0.000000");
								cellStr = dfomat.format(db);
							} else {
								cellStr = db.toPlainString();
							}
							break;
						case HSSFCell.CELL_TYPE_STRING:// 字符串
							cellStr = row.getCell(i).getStringCellValue();
							break;
						case HSSFCell.CELL_TYPE_BOOLEAN:// 布尔
							cellStr = String.valueOf(row.getCell(i)
									.getBooleanCellValue());
							break;
						case HSSFCell.CELL_TYPE_BLANK:// 空值
							cellStr = "";
							break;
						default:
							cellStr = row.getCell(i).getStringCellValue();
							break;
						}
					}
				} else {
					cellStr = null;
				}
				list.add(i, cellStr);
			}
			lists.add(list);
			list = null;
		}
		// 操作完毕后，记得要将打开的 XSSFWorkbook 关闭
		workbook.close();
		return lists;
	}

	// 读取内容
	public static List<List<String>> readXlsx(String filePath,
			HttpServletRequest request, int num) throws IOException {
		List<List<String>> lists = new ArrayList();
		// 创建 Excel 文件的输入流对象
		FileInputStream excelFileInputStream = new FileInputStream(filePath);
		// XSSFWorkbook 就代表一个 Excel 文件
		// 创建其对象，就打开这个 Excel 文件
		XSSFWorkbook workbook = new XSSFWorkbook(excelFileInputStream);
		// 输入流使用后，及时关闭！这是文件流操作中极好的一个习惯！
		excelFileInputStream.close();
		// XSSFSheet 代表 Excel 文件中的一张表格
		// 我们通过 getSheetAt(0) 指定表格索引来获取对应表格
		// 注意表格索引从 0 开始！
		XSSFSheet sheet = workbook.getSheetAt(0);
		// 步骤三 ： 循环读取表格并输出其内容
		// 开始循环表格数据,表格的行索引从 0 开始
		// employees.xlsx 第一行是标题行，我们从第二行开始, 对应的行索引是 1
		// sheet.getLastRowNum() : 获取当前表格中最后一行数据对应的行索引
		// 获得总列数 int coloumNum=sheet.getRow(0).getPhysicalNumberOfCells();
		// 获得总行数 int rowNum=sheet.getLastRowNum();
		for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
			// XSSFRow 代表一行数据
			XSSFRow row = sheet.getRow(rowIndex);
			if (row == null) {
				continue;
			}
			List<String> list = new ArrayList<String>();
			/*************************************************************/
			for (int i = 0; i < num; i++) {
				/*************************************************************/
				String cellStr = null;
				if (null != row.getCell(i)) {
					switch (row.getCell(i).getCellType()) {
					case HSSFCell.CELL_TYPE_NUMERIC:// 数值
						int dataFormat = row.getCell(i).getCellStyle()
								.getDataFormat();
						if (dataFormat == 14 || dataFormat == 176
								|| dataFormat == 178 || dataFormat == 180
								|| dataFormat == 181 || dataFormat == 182) {
							/*
							 * Date theDate = row.getCell(i).getDateCellValue();
							 * cellStr = dff.format(theDate);
							 */
							/*
							 * SimpleDateFormat dff = new
							 * SimpleDateFormat("yyyy-MM-dd"); double value =
							 * row.getCell(i).getNumericCellValue(); Date date =
							 * org
							 * .apache.poi.ss.usermodel.DateUtil.getJavaDate(
							 * value ); cellStr = dff.format(date);
							 */
							cellStr = Double.toString(row.getCell(i)
									.getNumericCellValue());
						} else {
							BigDecimal db = new BigDecimal(row.getCell(i)
									.getNumericCellValue());
							if (db.toString().indexOf(".") != -1) {
								java.text.DecimalFormat dfomat = new java.text.DecimalFormat(
										"0.000000");
								cellStr = dfomat.format(db);
							} else {
								cellStr = db.toPlainString();
							}
						}
						break;
					case HSSFCell.CELL_TYPE_STRING:// 字符串
						cellStr = row.getCell(i).getStringCellValue();
						break;
					case HSSFCell.CELL_TYPE_BOOLEAN:// 布尔
						cellStr = String.valueOf(row.getCell(i)
								.getBooleanCellValue());
						break;
					case HSSFCell.CELL_TYPE_BLANK:// 空值
						cellStr = "";
						break;
					default:
						cellStr = row.getCell(i).getStringCellValue();
						break;
					}
				} else {
					cellStr = null;
				}
				list.add(i, cellStr);
			}
			lists.add(list);
			list = null;
		}
		// 操作完毕后，记得要将打开的 XSSFWorkbook 关闭
		workbook.close();
		return lists;
	}

	
	
	/**
	 *
	 * @Title: setDataValidation
	 * @Description: 下拉列表元素不多的情况(255以内的下拉)
	 * @param sheet
	 * @param textList
	 *            列表内容
	 * @param firstRow
	 * @param endRow
	 * @param firstCol
	 * @param endCol
	 * @return DataValidation
	 * @throws
	 */
	public DataValidation setDataValidation(Sheet sheet,
			String[] textList, int firstRow, int endRow, int firstCol,
			int endCol) {
		DataValidationHelper helper = sheet.getDataValidationHelper();
		// 加载下拉列表内容
		DataValidationConstraint constraint = helper
				.createExplicitListConstraint(textList);
		constraint.setExplicitListValues(textList);
		// 设置数据有效性加载在哪个单元格上。四个参数分别是：起始行、终止行、起始列、终止列
		CellRangeAddressList regions = new CellRangeAddressList(
				(short) firstRow, (short) endRow, (short) firstCol,
				(short) endCol);
		// 数据有效性对象
		DataValidation data_validation = helper.createValidation(constraint,
				regions);
		return data_validation;
	}
	/**
	 * 设置列宽
	 * @param sheet HSSFSheet
	 * @param columnIndex 列数
	 * @param width 列宽
	 * @return
	 */
	public HSSFSheet setColumnWidth(HSSFSheet sheet, int columnIndex, int width) {
		sheet.setColumnWidth(columnIndex, width * 256 + 184);
		return sheet;
	}
	/**
	 * 设置行高
	 * @param row HSSFRow
	 * @param height 行高
	 * @return
	 */
	public HSSFRow setColumnWidth(HSSFRow row, int height) {
		row.setHeight((short)(44.25*height));
		return row;
	}

	/**
	 * 合并单元格
	 * @param sheet 
	 * @param firstRow 起始行
	 * @param lastRow 截至行
	 * @param firstCol 起始列
	 * @param lastCol 截至列
	 * @return
	 */
	public HSSFSheet setCellRangeAddress(HSSFSheet sheet, int firstRow,
			int lastRow, int firstCol, int lastCol) {
		// 合并单元格CellRangeAddress构造参数依次表示起始行，截至行，起始列， 截至列
		CellRangeAddress callRangeAddress = new CellRangeAddress(firstRow,
				lastRow, firstCol, lastCol);
		sheet.addMergedRegion(callRangeAddress);
		return sheet;
	}

	/**
	 * 列表首页的大title样式
	 * @param workbook
	 * @return
	 */
	public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) { // 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 16);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置底边框;
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		// 设置底边框颜色;
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		// 设置左边框;
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// 设置左边框颜色;
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		// 设置右边框;
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// 设置右边框颜色;
		style.setRightBorderColor(HSSFColor.BLACK.index);
		// 设置顶边框;
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// 设置顶边框颜色;
		style.setTopBorderColor(HSSFColor.BLACK.index);
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		// 设置背景颜色
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
		return style;
	} 
	
	/**
	 * 列数据信息单元格样式
	 * @param workbook
	 * @return
	 */
	public HSSFCellStyle getStyle(HSSFWorkbook workbook) { // 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 12);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置底边框;
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		// 设置底边框颜色;
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		// 设置左边框;
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// 设置左边框颜色;
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		// 设置右边框;
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// 设置右边框颜色;
		style.setRightBorderColor(HSSFColor.BLACK.index);
		// 设置顶边框;
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// 设置顶边框颜色;
		style.setTopBorderColor(HSSFColor.BLACK.index);
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		// 设置背景颜色
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE
				.getIndex());
		return style;
	} 
	
	/**
	 * 列数据信息单元格样式
	 * @param workbook
	 * @return
	 */
	public HSSFCellStyle getColumnNumCentStyle(HSSFWorkbook workbook) { // 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置字体大小
		font.setFontHeightInPoints((short) 11);
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置底边框;
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		// 设置底边框颜色;
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		// 设置左边框;
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// 设置左边框颜色;
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		// 设置右边框;
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// 设置右边框颜色;
		style.setRightBorderColor(HSSFColor.BLACK.index);
		// 设置顶边框;
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// 设置顶边框颜色;
		style.setTopBorderColor(HSSFColor.BLACK.index);
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(true);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		return style;
	} 
	/**
	 * 底部统计样式
	 * @param workbook
	 * @return
	 */
	public HSSFCellStyle getDownColumnTopStyle(HSSFWorkbook workbook) { // 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 11);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");

		font.setColor(HSSFColor.PINK.index);
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置底边框;
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		// 设置底边框颜色;
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		// 设置左边框;
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// 设置左边框颜色;
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		// 设置右边框;
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// 设置右边框颜色;
		style.setRightBorderColor(HSSFColor.BLACK.index);
		// 设置顶边框;
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// 设置顶边框颜色;
		style.setTopBorderColor(HSSFColor.BLACK.index);
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		// 设置背景颜色
		return style;
	}
	/**
	 * 样式
	 * @param style
	 * @return
	 */
	public HSSFCellStyle getStyle(HSSFCellStyle style) {
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 创建一个居中格式
		style.setWrapText(true); // 自动换行
		// 填充单元格
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		// 填颜色
		style.setFillForegroundColor(HSSFColor.WHITE.index);
		return style;
	}

	/**
	 * 设置字体
	 * @param fontStyle
	 * @return
	 */
	public HSSFFont setCellRangeAddress(HSSFFont fontStyle) {
		// 设置字体样式
		fontStyle.setFontName("Arial");
		// 设置字体高度
		fontStyle.setFontHeightInPoints((short) 8);
		// fontStyle.setColor(HSSFFont.COLOR_RED); //字体颜色
		// fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //宽度
		// fontStyle.setItalic(true); //是否使用斜体
		// fontStyle.setStrikeout(true); //是否使用划线
		return fontStyle;
	}
	
	
	public static void main(String[] args) throws IOException {
			// 读取内容
		String filePath= "F:\\work_file\\FILE_VERSION-1-28\\src\\main\\webapp\\excel\\控制计划信息.xls";
			// 创建 Excel 文件的输入流对象
			FileInputStream excelFileInputStream = new FileInputStream(filePath);
			// XSSFWorkbook 就代表一个 Excel 文件
			// 创建其对象，就打开这个 Excel 文件
			HSSFWorkbook workbook = new HSSFWorkbook(excelFileInputStream);
			// 输入流使用后，及时关闭！这是文件流操作中极好的一个习惯！
			//excelFileInputStream.close();
			// 注意表格索引从 0 开始！
			HSSFSheet sheet = workbook.getSheetAt(0);
			// XSSFRow 代表一行数据
			HSSFRow row = sheet.getRow(2);
			HSSFCell cell = row.getCell(2);
			System.out.println(cell);
			cell.setCellValue("Pre-Launch");
			
			FileOutputStream output=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\ww\\"+"ss.xls");  
			workbook.write(output);//写入磁盘  
	        output.close(); 
	        
	}
}
